secretlint を使って機密情報を git commit できない環境を作る
AWSアクセスキーセキュリティ意識向上委員会って何?
昨今、AWSのアクセスキーを漏洩させてしまうことが原因でアカウントへの侵入を受け、 多額の利用費発生・情報漏洩疑いなど重大なセキュリティ事案が発生するケースが実際に多々起きています。
そこで、アクセスキー運用に関する安全向上の取組みをブログでご紹介する企画をはじめました。
アクセスキーを利用する場合は利用する上でのリスクを正しく理解し、 セキュリティ対策を事前に適用した上で適切にご利用ください。
tl;dr
開発をはじめる前に、次の手順を実行しよう
シェルスクリプトの保存
次のシェルスクリプトを ~/.git-template/hooks/pre-commit
として保存しよう。
#!/bin/sh FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') [ -z "$FILES" ] && exit 0 echo "$FILES" | xargs docker run \ -v "$(pwd):$(pwd)" \ -w "$(pwd)" \ --rm \ secretlint/secretlint secretlint RET=$? if [ $RET -eq 0 ] ;then exit 0 else exit 1 fi
コマンド実行
次のふたつのコマンドを叩こう。
chmod +x ~/.git-template/hooks/* git config --global init.templatedir ~/.git-template
Docker のインストール
Docker をインストールしよう。
前置き
AWS のアクセスキーをはじめ、他者に知られると被害が発生するものは取り扱いに注意する必要があります。この記事では、こういった情報を機密情報と呼びます。
そもそもアクセスキーを発行しないようにすべきですが、ソフトウェア開発をする場合、そうも言っていられません。 CI/CD や、定期実行するソフトウェアに対して、権限を付与しなければならない場面も多いためです。
開発時に気をつけるべきケースは機密情報を git commit
してしまったことに気づかず git push
してしまうことです。これを機会的に防ぐ方法をまとめます。
やりたいこと
git commit
しようとするときに、 stage に上がっているファイル内に機密情報があると自動的にコミットを失敗させ、機密情報の位置を表示させます。
secretlint とは
secretlint はその名の通り、機密情報が含まれていないかをチェックし、もし機密情報があればエラーとともにその場所を表示してくれるツールです。
git-secrets に比べると、単純なコマンドラインということで様々な環境や Git リポジトリーに適用しやすいものとなっています。また、 Docker イメージも配布されているので、セットアップが簡単です。
サポートしている機密情報も多彩です。 2021 年 4 月時点で次をサポートしています。
- AWS
- GCP
- Slack
- ベーシック認証
- npm
- 秘密鍵
- SendGrid
- Kubernetes
Git pre-commit フック
git commit
前に何かさせたい場合は pre-commit フックを使います。
幸い、 secretlint 公式が pre-commit 用のスクリプトを公開してくれていますので、これを使いましょう。 Docker を使うバージョンに書き換えたものを掲載します。
#!/bin/sh FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') [ -z "$FILES" ] && exit 0 echo "$FILES" | xargs docker run \ -v "$(pwd):$(pwd)" \ -w "$(pwd)" \ --rm \ secretlint/secretlint secretlint RET=$? if [ $RET -eq 0 ] ;then exit 0 else exit 1 fi
ダブルクォーテーションで変数をくくっているなど、細部が異なっていますが読みやすさと可搬性を考慮した変更です。
git diff --cached --name-only --diff-filter=ACMR
というコマンドで stage に上がっており、追加、コピー、変更、名前変更されたファイル一覧を取得します。これらに対して secretlint でチェックをかける、というシェルスクリプトです。
Docker イメージの secretlint/secretlint でチェックしてくれる機密情報の種類はここで定義されています。 AWS や GCP 、 Slack など、開発者が普段使うものは定義されています。
最後の if
節ですが、 secretlint では失敗時に 1
以外のコードを返す場合があるようです。この場合を考慮して失敗はすべて 1
として返却し、 Git にコミットを続行させないようにするテクニックが使われています。
さて、このスクリプトを適当な Git リポジトリーの .git/hooks/
に pre-commit
という名前で保存し、実行権限をつけてください。すると、機密情報を stage して git commit
を打った際に次のようなメッセージが表示され、コミットできなくなります。
takagi.kensuke$ git commit /Users/takagi.kensuke/secretlint-sample/index.js 1:23 error [AWSAccessKeyID] found AWS Access Key ID: AKIASUZWCFAMGDUVMVRE @secretlint/secretlint-rule-preset-recommend > @secretlint/secretlint-rule-aws ✖ 1 problem (1 error, 0 warnings)
ここに表示している AWS アクセスキーはポリシーをまったく適用していない IAM ユーザーのものです。このように他者に知られても問題ない状態で実験してください。
Git リポジトリーのテンプレートディレクトリー指定
やりたいことはできましたが、 Git リポジトリーごとにファイルをコピーして実行権限をつけて、という操作は開発者のやることではありません。これらの手順を自動的にやってくれるよう設定しましょう。
Git ではリポジトリーのテンプレートディレクトリーを指定可能です。 git init
や git clone
する際に、指定したディレクトリーの内容をリポジトリーへコピーしてくれます。
ここでは ~/.git-template
というディレクトリーを作成し、これをテンプレートディレクトリーとして Git に設定しましょう。
mkdir -p ~/.git-template/hooks git config --global init.templatedir ~/.git-template
最後に、前節で紹介した pre-commit スクリプトを ~/.git-template/hooks/pre-commit
として保存すれば完了です。
他の環境でもこの設定を使いたい、という場合は次のふたつをコピーすることで可能です。 GitHub などに push しておくと共有が楽なのでオススメです。
~/.gitconfig
~/.git-template
まとめ
人間はミスする生き物ですが、この記事ではミスしても事故を防ぐことが可能な方法を紹介しました。
ただ、今回紹介した方法は、各開発者が事前に設定して意味があるものです。何らかの理由でこういった前提が崩れてしまう場合、公式ドキュメントに書かれている方法でプロジェクトごとに設定しましょう。